package ssm.shopping.shiro;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;

import ssm.shopping.entity.Cust;
import ssm.shopping.service.interfaces.ICustService;
import ssm.shopping.util.ResultCode;
import ssm.shopping.util.ResultData;

@Component
public class SecurityRealm extends AuthorizingRealm{
	
	public static final String SESSION_USER_KEY = "shopping-";
	
	@Resource
	ICustService custService;

	/**
	 * 用户登陆控制
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		 Cust cust = (Cust) SecurityUtils.getSubject().getSession().getAttribute(SecurityRealm.SESSION_USER_KEY);  
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
        info.addRole(cust.getRole().trim());
        return info;  
	}

	/**
	 * 访问控制的过程，即决定是否有权限去访问受保护的资源。
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		  // 把token转换成User对象  
		Cust userLogin = tokenToUser((UsernamePasswordToken) token);  
        // 验证用户是否可以登录  
		ResultData resultData = new ResultData();
		try {
			resultData = custService.login(userLogin.getCustMbl(),userLogin.getCustPwd());
		} catch (Exception e) {
			e.printStackTrace();
		}  
        if(!resultData.getCode().equals(ResultCode.SUCCESS.getCode()))  
            return null; // 异常处理，找不到数据
        Cust cust = (Cust)resultData.getData();
        
        // 设置session  
        Session session = SecurityUtils.getSubject().getSession();  
        session.setAttribute(SecurityRealm.SESSION_USER_KEY+cust.getId(), cust);   
        //当前 Realm 的 name  
        String realmName = this.getName();  
        //登陆的主要信息: 可以是一个实体类的对象, 但该实体类的对象一定是根据 token 的 username 查询得到的.  
//      Object principal = ui.getUsername();  
        Object principal = token.getPrincipal();  
        return new SimpleAuthenticationInfo(principal, userLogin.getCustPwd(), cust.getCustMbl());  
	}
	
	private Cust tokenToUser(UsernamePasswordToken authcToken) {  
		Cust cust = new Cust();  
		cust.setCustMbl(authcToken.getUsername());  
		cust.setCustPwd(String.valueOf(authcToken.getPassword()));  
        return cust;  
    }  

}
